package com.metadata_system.common.service;


import com.alibaba.fastjson.JSON;
import com.metadata_system.common.db.entity.*;
import com.metadata_system.common.db.mapper.*;
import com.metadata_system.common.dto.ApiResult;
import com.metadata_system.common.dto.JwtToken;
import com.metadata_system.common.dto.ProjectLogCount;
import com.metadata_system.common.enums.AllConst;
import com.metadata_system.common.request.UserListRequest;
import com.metadata_system.common.utils.RegexUtils;
import com.metadata_system.system.response.UserResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

@Service
@Slf4j
public class CommonUserService {
    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired(required = false)
    UserMapper userMapper;

    @Autowired(required = false)
    AuthTokenMapper authTokenMapper;

    @Autowired
    UserOperationLogService userOperationLogService;


    public String getUserRole(JwtToken jwtToken) {
        return this.userMapper.getRoleById(jwtToken.decodeID());
    }


    /**
     * 检查格式
     *
     * @param user
     * @return
     */
    public static ApiResult CheckRule(User user, boolean isUpdate) {
        if (!isUpdate || !StringUtils.isBlank(user.getName())) {
            if (StringUtils.isBlank(user.getName()) || (user.getName().length() < 2 || user.getName().length() > 20)) {
                return ApiResult.error("姓名 格式错误");
            }
        }

        if (!isUpdate || !StringUtils.isBlank(user.getUsername())) {
            if (StringUtils.isBlank(user.getUsername()) || !RegexUtils.checkUsername(user.getUsername())) {
                return ApiResult.error("账号 格式错误 必须由a-zA-Z0-9_组成，长度在(2,30)个字符");
            }
        }

        if (!isUpdate || !StringUtils.isBlank(user.getPassword())) {
            if (StringUtils.isBlank(user.getPassword()) || (user.getPassword().length() < 6 || user.getPassword().length() > 30)) {
                return ApiResult.error("密码 格式错误");
            }
        }
        return ApiResult.success();
    }

    /**
     * 管理员-列表
     */
    @SneakyThrows
    public ApiResult getList(UserListRequest userParams) {
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();

        if (!StringUtils.isBlank(userParams.getUserType())) {
            userParams.setUserType(userParams.getUserType());
        }
        if (!StringUtils.isBlank(userParams.getFilterIds())) {
            try {
                criteria.andNotIn("id", Arrays.asList(userParams.getFilterIds().split(",")));
            } catch (Exception e) {
                return ApiResult.error("过滤ID格式错误");
            }
        }
        if (!StringUtils.isBlank(userParams.getKeywords())) {
            criteria.andCondition("(name like '%" + userParams.getKeywords() + "%' or username like '%" + userParams.getKeywords() + "%')");
        }
        if (userParams.getCurrRole().equals("Super")) {
            criteria.andIn("role", Arrays.asList("Super","System","User"));
        }
        if (userParams.getCurrRole().equals("System")) {
            criteria.andIn("role", Arrays.asList("User"));
        }

        // 1.查询条件参数
        // 1-2.普通查询参数
        if (!StringUtils.isBlank(userParams.getUsername())) {
            criteria.andLike("username", "%" + userParams.getUsername() + "%");
        }
        if (!StringUtils.isBlank(userParams.getName())) {
            criteria.andLike("name", "%" + userParams.getName() + "%");
        }
        if (!StringUtils.isBlank(userParams.getUserType())) {
            criteria.andEqualTo("userType", userParams.getUserType());
        }
        if (!StringUtils.isBlank(userParams.getRole())) {
            criteria.andEqualTo("role", userParams.getRole());
        }
//        criteria.andEqualTo("userType", userParams.getUserType());
        if (userParams.getStatus() != null) {
            criteria.andEqualTo("status", userParams.getStatus());
        }
        if (userParams.getAccessProviderId() != null) {
            criteria.andEqualTo("accessProviderId", userParams.getAccessProviderId());
        }

        if (userParams.getParams() != null) {
            criteria.andEqualTo("params", userParams.getParams());
        }
        // 设置查询时间段
        userParams.setConditionTime(userParams.getCreatedTime(), criteria, "createdTime");

        // 2.设置排序
        userParams.setOrder(example, "id,createdTime");

        // 3.查询: 总条数,列表数据
        int total = this.userMapper.selectCountByExample(example);
        List<User> userList = new ArrayList<>();
        if (total > 0) {
            userList = this.userMapper.selectByExampleAndRowBounds(example, userParams.getRowRunds());
        }
        List<UserResponse> userResponses = UserResponse.formatData(userList);
        return ApiResult.successPage(userResponses, total);
    }

    /**
     * 创建-管理员
     *
     * @param userParams
     * @param currRole
     * @param sytemUserId
     * @return
     */
    public ApiResult create(User userParams, String currRole, Integer sytemUserId) {
        // 1.数据格式校验
        ApiResult result = CheckRule(userParams, false);
        if (result.getCode() > 0) {
            return result;
        }

        if (this.userMapper.selectCount(User.builder()
                .username(userParams.getUsername())
                .build()) > 0) {
            return ApiResult.error("用户名 已经存在");
        }

        if (!currRole.equals("Super") && (userParams.getRole().equals("System") || userParams.getRole().equals("Super"))) {
            return ApiResult.error("只有【超级管理员】才能创建: 【系统管理员】");
        }


        User insertUser = User.builder()
                .username(userParams.getUsername())
                .password(passwordEncoder.encode(userParams.getPassword()))
                .role(userParams.getRole())
                .name(userParams.getName())
                .status(1)
                .params(0)
                .avatar(userParams.getAvatar())
                .createdTime(new Date())
                .isLogicToolAccess(userParams.getIsLogicToolAccess())
                .unReadMessageTotal(0)
                .runningQueueTotal(0)
                .unLockLoginTime(null)
                .build();

        // 3.插入数据
        this.userMapper.insert(insertUser);
        insertUser.setId(this.userMapper.getLastInsertId());
        insertUser.setPassword("******");

        // 4.操作日志-新增
        userOperationLogService.insert(UserOperationLog.builder()
                .userId(sytemUserId)
                .type("Create.User")
                .content("创建用户: "+insertUser.getUsername()+"|"+ AllConst.UserRoleMap.get(insertUser.getRole()))
                .params(JSON.toJSONString(insertUser))
                .build());

        return ApiResult.success(insertUser);
    }


    /**
     * 更新-管理员
     *
     * @param userParams
     * @param currRole
     * @param sytemUserId
     * @return
     */
    public ApiResult update(User userParams, String currRole, Integer sytemUserId) {
        // 1.参数检查
        if (userParams.getId() == null) {
            return ApiResult.error("用户ID 必须");
        }

        // 2.检查格式
        ApiResult result = CheckRule(userParams, true);
        if (result.getCode() > 0) {
            return result;
        }

        // 3.数据检查
        User currUser = this.userMapper.selectByPrimaryKey(userParams.getId());
        if (currUser == null) {
            return ApiResult.error("用户信息 不存在");
        }
        User updateUser = User.builder()
                .id(currUser.getId())
                .params(currUser.getParams())
                .build();

//        if ((currRole.equals("Super") || currRole.equals("GeneralManager")) && currUser.getUserType().equals("Admin")) {
//            return ApiResult.error("只有【管理员】才能管理: 【经理/管理员】");
//        }
//        if (currUser.getUserType().equals("SysUser")) {
//            if (!(userParams.getRole().equals("Admin") || userParams.getRole().equals("GeneralManager") || userParams.getRole().equals("Manager"))) {
//                return ApiResult.error("系统管理员角色 错误");
//            }
//        }
//        if (currUser.getUserType().equals("Staff")) {
//            if (userParams.getRole() != null && !(userParams.getRole().equals("Checker") || userParams.getRole().equals("Dealer"))) {
//                return ApiResult.error("职员角色 错误");
//            }
//        }

        // 4.提取更新数据
        boolean isNeedUpdate = false;
        if (!StringUtils.isBlank(userParams.getPassword()) && !StringUtils.isBlank(userParams.getPassword())) {
            if (userParams.getPassword().length() < 6) {
                return ApiResult.error("密码 长度必须大于6位");
            }
//            log.info("密码: " + userParams.getPassword());
            updateUser.setPassword(passwordEncoder.encode(userParams.getPassword()));
            isNeedUpdate = true;
        }
        if (!StringUtils.isBlank(userParams.getName()) && !StringUtils.isBlank(userParams.getName())) {
            updateUser.setName(userParams.getName());
            isNeedUpdate = true;
        }
        if (!StringUtils.isBlank(userParams.getRole()) && !StringUtils.isBlank(userParams.getRole())) {
            updateUser.setRole(userParams.getRole());
            isNeedUpdate = true;
        }
        if (userParams.getStatus() != null) {
            if (currUser.getStatus() == 2 && userParams.getStatus() == 1) {
                updateUser.setUnLockLoginTime(new Date());
            }
            updateUser.setStatus(userParams.getStatus());
            isNeedUpdate = true;
        }
        if (userParams.getAvatar() != null && !StringUtils.isBlank(userParams.getAvatar())) {
            updateUser.setAvatar(userParams.getAvatar());
            isNeedUpdate = true;
        }
        if (userParams.getIsLogicToolAccess() != null) {
            updateUser.setIsLogicToolAccess(userParams.getIsLogicToolAccess());
            isNeedUpdate = true;
        }
        if (!isNeedUpdate) {
            return ApiResult.success("无可更新数据");
        }

        // 3.执行更新操作
        this.userMapper.updateByPrimaryKeySelective(
                updateUser
        );

        // 4.操作日志-新增
        userOperationLogService.insert(UserOperationLog.builder()
                .userId(sytemUserId)
                .type("Update.User")
                .content("更新用户")
                .params(JSON.toJSONString(updateUser))
                .build());

        return ApiResult.success("更新成功");
    }

    /**
     * 删除-管理员
     */
    public ApiResult deleteUser(Integer id, String currRole, Integer sytemUserId) {
        if (id == null) {
            return ApiResult.error("用户ID 必须");
        }
        User currUser = this.userMapper.selectByPrimaryKey(id);
        if (currRole.equals("System") && !currUser.getRole().equals("Super")) {
            return ApiResult.error("只有【超级管理员】才能管理: 【系统管理员】");
        }

        this.userMapper.deleteByPrimaryKey(id);


        // 4.操作日志-新增
        userOperationLogService.insert(UserOperationLog.builder()
                .userId(sytemUserId)
                .type("Delete.User")
                .content("删除用户")
                .params(JSON.toJSONString(currUser))
                .build());
        return ApiResult.success("操作成功");
    }

    @Autowired
    UserLoginLogService userLoginLogService;
    @Autowired
    CommonUserService commonUserService;

    /**
     * 清空登录错误
     *
     * @param userId
     * @param sytemUserId
     * @return
     */
    public ApiResult clearLoginDayError(Integer userId, Integer sytemUserId) {
        User currUser = this.userMapper.selectOne(
                User.builder()
                        .id(userId)
                        .build()
        );
        if (currUser == null) {
            return ApiResult.error("用户信息 不存在");
        }
        userLoginLogService.clearLoginError(userId);

        // 4.操作日志-新增
        userOperationLogService.insert(UserOperationLog.builder()
                .userId(sytemUserId)
                .type("User.ClearLoginDayError")
                .content("清空用户登录错误: "+currUser.getUsername())
                .params(JSON.toJSONString(currUser))
                .build());
        return ApiResult.success();
    }



    @Autowired(required = false)
    MessageMapper messageMapper;
    @Autowired(required = false)
    ProjectLogMapper projectLogMapper;


    /**
     * 获取未读数量
     * @param userId 用户ID
     * @return
     */
    public ApiResult getUnReadCount(Integer userId) {
        Integer all=0;
        Map<String,Object> countMap = new HashMap<String,Object>();
        List<ProjectLogCount> projectLogMap = this.projectLogMapper.countProjectUnreadMessages(userId);
        for (ProjectLogCount map : projectLogMap) {
            all=all+map.getHandler()+map.getApply();
        }
        Integer projectUserTotal = this.messageMapper.countUnReadMessage(userId);
        all=all+projectUserTotal;
        countMap.put("all",all);
        countMap.put("projectLog",projectLogMap);
        countMap.put("projectUser",projectUserTotal);
        return ApiResult.success(countMap);
    }
}
